using System;
using System.ServiceModel;

using Pegasus.Log4Net;

namespace Pegasus.ServiceModel
{
	/// <summary>
	/// This class is used to receive messages from the peer network and pass
	/// them on to the peer network manager.
	/// </summary>
	[ServiceBehavior( InstanceContextMode = InstanceContextMode.Single )]
	internal class BroadcastReceiver : IBroadcast
	{
		// Local Instance Values
		private ILog m_log = LogManager.GetLogger( typeof( BroadcastReceiver ) );
		private PeerNetworkManager m_peerNetManager;

		/// <summary>
		/// Initializes a new instance of the <see cref="BroadcastReceiver"/> class.
		/// </summary>
		public BroadcastReceiver( PeerNetworkManager peerNetManager )
		{
			m_log.DebugFormat( "BroadcastReceiver( peerNetManager = {0} )", peerNetManager );
			m_peerNetManager = peerNetManager;
		}

		/// <summary>
		/// Sends the message.
		/// </summary>
		/// <param name="sender">The sender.</param>
		/// <param name="message">The message.</param>
		public void SendBroadcastMessage( string sender, object message )
		{
			m_log.DebugFormat( "BroadcastReceiver:SendBroadcastMessage( sender = {0}, message = {1} )", sender, message );
			m_peerNetManager.ReceivedBroadcastMessage( sender, message );
		}

		/// <summary>
		/// Notification that a node has entered the mesh.
		/// </summary>
		/// <param name="nodeInfo">The node info.</param>
		public void SendNodeEnter( NodeData nodeInfo )
		{
			m_log.DebugFormat( "BroadcastReceiver:SendNodeEnter( nodeInfo = {0} {1} {2} {3} )", nodeInfo.Name, nodeInfo.MachineName, nodeInfo.IPAddress, nodeInfo.Port );
			m_peerNetManager.ReceivedBroadcastNodeEnter( nodeInfo );
		}

		/// <summary>
		/// Notification that a node has exited the mesh.
		/// </summary>
		/// <param name="nodeInfo">The node info.</param>
		public void SendNodeExit( NodeData nodeInfo )
		{
			m_log.DebugFormat( "BroadcastReceiver:SendNodeExit( nodeInfo = {0} {1} {2} {3} )", nodeInfo.Name, nodeInfo.MachineName, nodeInfo.IPAddress, nodeInfo.Port );
			m_peerNetManager.ReceivedBroadcastNodeExit( nodeInfo );
		}

		/// <summary>
		/// Sends a request to the group to see if anyone has the node
		/// info for the given node.
		/// </summary>
		/// <param name="sender">The name of the node that sent the message.</param>
		/// <param name="nodeName">Name of the node that they are looking for.</param>
		public void SendNodeWhoIs( string sender, string nodeName )
		{
			m_log.DebugFormat( "BroadcastReceiver:SendNodeWhoIs( sender = {0}, nodeName = {1} )", sender, nodeName );
			m_peerNetManager.ReceivedBroadcastNodeWhoIs( sender, nodeName );
		}

		/// <summary>
		/// Sends the node fault message to tell the other nodes that
		/// this guy has a problem.
		/// </summary>
		/// <param name="sender">The name of the node that sent the message.</param>
		/// <param name="nodeInfo">The node info.</param>
		public void SendNodeFault( string sender, NodeData nodeInfo )
		{
			m_log.DebugFormat( "BroadcastReceiver:SendNodeFault( sender = {0}, nodeInfo.Name = {1} )", sender, nodeInfo.Name );
			m_peerNetManager.ReceivedBroadcastNodeFault( sender, nodeInfo );
		}

		/// <summary>
		/// Sends the hartbeat message from a given node.
		/// </summary>
		/// <param name="sender">The name of the node that sent the message.</param>
		public void SendHartbeat( string sender )
		{
			m_log.DebugFormat( "BroadcastReceiver:SendHartbeat( sender = {0} )", sender );
			m_peerNetManager.ReceivedBroadcastHartbeat( sender );
		}
	}
}
